﻿using Moq;
using NUnit.Framework;
using System.Threading.Tasks;
using TabbedTemplate.Models;
using TabbedTemplate.Services;
using TabbedTemplate.ViewModels;

namespace UnitTest.ViewModels
{
    public class TestNewIndexPageViewModel
    {
        [Test]
        public async Task TestStoreTappedCommand()
        {
            var punchNavigationServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;


            var newIndexPageViewModel = new NewIndexPageViewModel(null, null, mockPunchNavigationService,
                null, null);
            await newIndexPageViewModel.StoreTappedCommandFunction("ChineseFood");
            punchNavigationServiceMock.Verify(
                p => p.NavigateToAsync(
                    ContentNavigationConstant.IndexPage, Tag.ChineseRestuarant),
                Times.Once);
        }

        [Test]
        public async Task TestSearchCommand()
        {
            var punchNavigationServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var newIndexPageViewModel = new NewIndexPageViewModel(null, null, mockPunchNavigationService,
                null, null);
            await newIndexPageViewModel.SearchCommandFunction();
            punchNavigationServiceMock.Verify(
                p => p.NavigationToAsync(
                    ContentNavigationConstant.QueryPage),
                Times.Once);
        }

        [Test]
        public async Task TestChangeCityCommand()
        {
            var punchNavigationServiceMock = new Mock<IPunchNavigationService>();
            var mockPunchNavigationService = punchNavigationServiceMock.Object;
            var newIndexPageViewModel = new NewIndexPageViewModel(null, null, mockPunchNavigationService,
                null, null);
            await newIndexPageViewModel.ChangeCityCommandFunction();
            punchNavigationServiceMock.Verify(
                p => p.NavigationToAsync(
                    ContentNavigationConstant.CityLocations),
                Times.Once);
        }

        /// <summary>
        /// 没有获取过定位，并且可以获取当前位置，并且切换城市。
        /// </summary>
        /// <returns></returns>
        [Test]
        public async Task TestPageAppearingCommandWithoutCurrentCityWithPositionChangeCity()
        {
            var alertServiceMock = new Mock<IAlertService>();
            var mockAlertService = alertServiceMock.Object;
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var locationServiceMock = new Mock<ILocationService>();
            var mockLocationService = locationServiceMock.Object;
            var NewIndexPageViewModel =
                new NewIndexPageViewModel(null, mockLocationService, null, mockPreferenceStorage, mockAlertService);
            var postionToReturn = new Position
            {
                Latitude = 39.915,
                Longitude = 116.404
            };
            var cityToReturn = "";
            locationServiceMock.Setup(p => p.GetCurrentLocation()).ReturnsAsync(postionToReturn);
            preferenceStorageMock.Setup(p => p.Get("CurrentCity", ""))
                .Returns("");

            locationServiceMock.Setup(p => p.GetCityByPosition(
                postionToReturn)).ReturnsAsync(cityToReturn);
            alertServiceMock.Setup(p => p.ShowAlert("提示",
                "识别到当前城市为 " + cityToReturn + " 是否切换到当前城市", "确定", "取消")).ReturnsAsync(true);
            await NewIndexPageViewModel.PageAppearingCommandFunction();
            alertServiceMock.Verify(p => p.ShowAlert("提示",
                "识别到当前城市为 " + cityToReturn + " 是否切换到当前城市", "确定", "取消"), Times.Once);

            preferenceStorageMock.Verify(p => p.Set("City", It.IsAny<string>()), Times.AtLeastOnce);

        }

        /// <summary>
        /// 没有获取过定位，并且可以获取当前位置，并且不切换城市。
        /// </summary>
        /// <returns></returns>
        [Test]
        public async Task TestPageAppearingCommandWithoutCurrentCityWithPositionNotChangeCity()
        {
            var alertServiceMock = new Mock<IAlertService>();
            var mockAlertService = alertServiceMock.Object;
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var locationServiceMock = new Mock<ILocationService>();
            var mockLocationService = locationServiceMock.Object;
            var NewIndexPageViewModel =
                new NewIndexPageViewModel(null, mockLocationService, null, mockPreferenceStorage, mockAlertService);
            var postionToReturn = new Position
            {
                Latitude = 39.915,
                Longitude = 116.404
            };

            var cityToReturn = "南京市";
            locationServiceMock.Setup(p => p.GetCurrentLocation()).ReturnsAsync(postionToReturn);
            preferenceStorageMock.Setup(p => p.Get("CurrentCity", ""))
                .Returns("");

            locationServiceMock.Setup(p => p.GetCityByPosition(
                postionToReturn)).ReturnsAsync(cityToReturn);
            alertServiceMock.Setup(p => p.ShowAlert("提示",
                "识别到当前城市为 " + cityToReturn + " 是否切换到当前城市", "确定", "取消")).ReturnsAsync(false);
            await NewIndexPageViewModel.PageAppearingCommandFunction();

            alertServiceMock.Verify(p => p.ShowAlert("提示",
                "识别到当前城市为 " + cityToReturn + " 是否切换到当前城市", "确定", "取消"), Times.Once);

            preferenceStorageMock.Verify(p => p.Set("City", It.IsAny<string>()), Times.AtLeastOnce);

            Assert.IsFalse(cityToReturn == NewIndexPageViewModel.City);

        }

        [Test]
        public async Task TestPageAppearingCommandWithException()
        {
            var alertServiceMock = new Mock<IAlertService>();
            var mockAlertService = alertServiceMock.Object;
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            //var geoLocationServiceMock = new Mock<IGeoLocationService>();
            //var mockGeoLocationService = geoLocationServiceMock.Object;
            var locationServiceMock = new Mock<ILocationService>();
            var mockLocationService = locationServiceMock.Object;
            var newIndexPageViewModel =
                new NewIndexPageViewModel(null, mockLocationService, null, mockPreferenceStorage, mockAlertService);

        }

        /// <summary>
        /// 没有定位过，且无法获取当前位置。
        /// </summary>
        /// <returns></returns>
        [Test]
        public async Task TestPageAppearingCommandWithoutCurrentCityWithoutPosition()
        {
            var alertServiceMock = new Mock<IAlertService>();
            var mockAlertService = alertServiceMock.Object;
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var locationServiceMock = new Mock<ILocationService>();
            var mockLocationService = locationServiceMock.Object;
            var newIndexPageViewModel =
                new NewIndexPageViewModel(null, mockLocationService, null, mockPreferenceStorage, mockAlertService);

            locationServiceMock.Setup(p => p.GetCurrentLocation()).ReturnsAsync((Position)null);
            preferenceStorageMock.Setup(p => p.Get("CurrentCity", ""))
                .Returns("");

            await newIndexPageViewModel.PageAppearingCommandFunction();
            alertServiceMock.Verify(p => p.ShowAlert("提示", "当前未开启定位", "确定"), Times.Once);
            preferenceStorageMock.Verify(p => p.Set("City", It.IsAny<string>()), Times.AtLeastOnce);



        }

        //已经存储过CurrentCity
        [Test]
        public async Task TestPageAppearingCommandWithCurrentCity()
        {
            var alertServiceMock = new Mock<IAlertService>();
            var mockAlertService = alertServiceMock.Object;
            var preferenceStorageMock = new Mock<IPreferenceStorage>();
            var mockPreferenceStorage = preferenceStorageMock.Object;
            var newIndexPageViewModel =
                new NewIndexPageViewModel(null, null, null, mockPreferenceStorage, mockAlertService);
            preferenceStorageMock.Setup(p => p.Get("City", ""))
                .Returns("北京市");

            await newIndexPageViewModel.PageAppearingCommandFunction();
            preferenceStorageMock.Verify(p => p.Get("City", "北京市"), Times.Once);

        }

    }
}
